package br.cn.evo.util;

import br.cn.evo.util.EnumTypes.FitnessPart;

public class Formulas {
	
	public static double lift(FitnessPart fi, double wingArea, 
			double velocity, double angleOfAttack){
		
		double cl = 0.0;
		double lift = 0.0;
		//lift / AoA = 0
		if( (fi == FitnessPart.I) || (fi == FitnessPart.V) ){
			cl = liftCoeficient(0);
			lift = 0.5 * cl * Constants.airDensity_1 * wingArea/3 * Math.pow(velocity, 2);
		}
		
		if( fi == FitnessPart.III){
			cl = liftCoeficient(0);
			lift = 0.5 *cl * (Constants.airDensity_3) * wingArea/3 * Math.pow(velocity, 2);
		}
		
		//Decolando
		if(fi == FitnessPart.II){
			if( (angleOfAttack >= GlobalParameters.minAngleAscending) &&
					(angleOfAttack <=GlobalParameters.maxAngleAscending) ){
				cl = liftCoeficient(angleOfAttack);
				//lift = cl * (Constants.airDensity_2) * wingArea * Math.pow(velocity, 2);
				lift = 0.5 * cl * (Constants.airDensity_2) * wingArea/3 * Math.pow(velocity, 2);
				
				//Correção ascending
				double t = Math.sin(Math.toRadians(angleOfAttack));
				lift = lift * t;
			}else{
				return 0;
			}
		}
		
		//Pousando
		if(fi == FitnessPart.IV){
			if( (angleOfAttack >= GlobalParameters.minAngleDescending) &&
					(angleOfAttack <=GlobalParameters.maxAngleDescending) ){
				cl = liftCoeficient(angleOfAttack);
				lift = 0.5 *cl * (Constants.airDensity_2) * wingArea/3 * Math.pow(velocity, 2);
				//Correção ascending
				lift = lift * (Math.sin(Math.toRadians(angleOfAttack)));
			}else{
				return 0;
			}
		}
		
		return lift;
	}
	
	public static double drag(FitnessPart fi, double wingArea, double velocity){
		double drag = 0.5*wingArea*GlobalParameters.dragCoeficient*Math.pow(velocity, 2);
		if( (fi == FitnessPart.I) || (fi == FitnessPart.V) ){
			drag *= Constants.airDensity_1/3;
		}
		if( fi == FitnessPart.III ){
			drag *= Constants.airDensity_3/3;
		}
		if( (fi == FitnessPart.II) || (fi == FitnessPart.IV) ){
			drag *= Constants.airDensity_2/3;
		}
		return drag;
	}
	
	public static double liftCoeficient(double angleOfAttack){
		if(angleOfAttack > 22)
			//stall
			return 0;
		double cl = angleOfAttack/20 + 0.5;
		//double cl = 2 * Math.PI * Math.toRadians(angleOfAttack);
		return cl;
	}
	
	public static double fuelWaste(double thrust){
		//double ret = 166*Math.pow(velocity, 1.25);
		double ret = Math.pow(thrust, 1/1.4)/25000;
		return ret;
	}
	
	//Equacao horaria do MUV: S = So + Vo + 0,5.α.t
	public static double MUV(double So, double Vo, double a, double t){
		return (So + Vo + (0.5*a*Math.pow(t, 2)));
	}
	
	//Equacao da velocidade, em funcao do tempo: V = Vo + α . t ===> t = (V-Vo)/a 
	public static double TIME(double V, double Vo, double a){
		double r = (V-Vo)/a;
		return (r >= 0) ? r : -1*r;
	}
	
	//Calcular altura verticalS
	public static double VERTICAL(double V, double AoA, double altitude){
		double radAngle = Math.toRadians(AoA);
		return altitude/Math.sin(radAngle);
	}
	
	//Torricelli
	public static double TORRI_ACCEL(double delta_distance, double V, double Vo){
		double ac = (Math.pow(V, 2) - Math.pow(Vo, 2)) / (delta_distance);
		return ac;
	}
	
	public static double velocityByThrust(double thrust){
		double power = GlobalParameters.rotatePowerEngine;
		double effi = GlobalParameters.efficiency;
		double velocity = (power*effi)/thrust;
		return velocity/3.6;
	}
	
	
		
}
